package transform.inline

import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.FieldVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.ModuleVisitor
import org.objectweb.asm.Opcodes

class RFileMinifyClassVisitor extends ClassVisitor {

    // 解析R文件
    private static Map<String, Integer> resourceIds = null

    RFileMinifyClassVisitor(ClassVisitor classVisitor) {
        super(Opcodes.ASM7, classVisitor)
    }

    private String className

    @Override
    void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        className = name
        println("##### visit name=$name  signature=$signature  superName=$superName  interfaces=$interfaces")
        // 替换类名和包名
        if (name.startsWith("com/xfhy/mylibrary2/MySecondActivity")) {
            super.visit(version, access, name.replaceAll("com/xfhy/mylibrary2/MySecondActivity", "cao/nim/dasjhdk/MyTestActivity"),
                    signature, superName, interfaces)
            return
        }
        super.visit(version, access, name, signature, superName, interfaces)
    }

    @Override
    void visitSource(String source, String debug) {
        println("className=$className  visitSource source=$source  debug=$debug")
        // 替换类名
        if ("MySecondActivity.java".equals(source)) {
            super.visitSource("MyTestActivity.java", debug)
            return
        }
        super.visitSource(source, debug)
    }

    @Override
    ModuleVisitor visitModule(String name, int access, String version) {
        return super.visitModule(name, access, version)
    }

    @Override
    MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        if (resourceIds == null) {
            resourceIds = RFileMinifier.parseRFile()
        }

        //println("visitMethod -------signature=$signature  exceptions=$exceptions  name=$name  descriptor=$descriptor")

        // 查找R资源引用
        MethodVisitor methodVisitor = cv.visitMethod(access, name, descriptor, signature, exceptions)
        methodVisitor = new MethodInliner(methodVisitor, resourceIds)
        return methodVisitor
//        if (name.startsWith("com/xfhy/mylibrary2/")) {
//            return super.visitMethod(version, access, name.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), descriptor, signature, exceptions)
//        }
//        return super.visitMethod(access, name, descriptor, signature, exceptions)
    }

    @Override
    FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
        // 这里直接拿到className,就知道是那个类了,再拿出属性的名称,就能替换成新的值了
        println("visitField className=$className -------signature=$signature   name=$name  descriptor=$descriptor")
        if (cv != null) {
            FieldVisitor fieldVisitor = cv.visitField(access, name, descriptor, signature, value)
            if (name.contains("TAG2")) {
                return fieldVisitor
            }
        }
        if (name.startsWith("com/xfhy/mylibrary2/")) {
            return super.visitField(access, name.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), signature, value)
        }
        return super.visitField(access, name, descriptor, signature, value)
    }

    @Override
    void visitOuterClass(String owner, String name, String descriptor) {
        //println("visitOuterClass ##### visitOuterClass owner=$owner name=$name descriptor=$descriptor ")
        if (name.startsWith("com/xfhy/mylibrary2/")) {
            super.visitOuterClass(owner, name.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), descriptor)
        }
        super.visitOuterClass(owner, name, descriptor)
    }

    @Override
    void visitInnerClass(String name, String outerName, String innerName, int access) {
        //println("visitInnerClass @@@@@@ visitInnerClass name=$name outerName=$outerName innerName=$innerName")
        if (name.startsWith("com/xfhy/mylibrary2/")) {
            super.visitInnerClass(name.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), outerName, innerName, access)
        }
        super.visitInnerClass(name, outerName, innerName, access)
    }
}